#include "MovementHandler.h"
#include <iostream>
#include <QMouseEvent>

#include "ConfigurationManagerDialog.h"

namespace ui {

MovementHandler::MovementHandler(QWidget *_parent, ConfigurationManagerDialog& cfgMgr) :
    QObject(_parent), cfgMgrDiag(cfgMgr), parent(_parent), clicked(false), selectedNode(NULL),
    selectedNodeIndex(0) {
}

bool MovementHandler::eventFilter(QObject *obj, QEvent *event) {
    if(obj == cfgMgrDiag.getWidget()) {
        if(event->type() == QEvent::Close) {
            // todo
        }
    }
    else { // for mainWidget
        if(event->type() == QEvent::Resize) {
            if(!cfgMgrDiag.nodesMappedOk)
                cfgMgrDiag.mapNodes();

            else {
                cfgMgrDiag.linesDrawn = false;
                cfgMgrDiag.getWidget()->update();
            }
        }
        else if(event->type() == QEvent::MouseButtonPress) {
            const QPoint clickPos = static_cast<QMouseEvent*>(event)->pos();
            bool found = false;

            foreach(GraphNode *node, cfgMgrDiag.nodes()) {
                QWidget *widget = node->getWidget();
                QRect rect      = widget->geometry();

                if(rect.contains(clickPos)) {
                    found = clicked = true;
                    selectedNode = widget;
                    selectedNodeIndex = node->getMeasIndex();
                    selectedNodeGeom = widget->geometry();

                    cfgMgrDiag.displayDetails();

                    break;
                }
            }

            if(!found) {
                selectedNode = NULL;
                cfgMgrDiag.linesDrawn = false;
                cfgMgrDiag.clearDetails();
            }

            cfgMgrDiag.getWidget()->update();
        }
        else if(event->type() == QEvent::MouseButtonRelease) {
            if(clicked) {
                clicked = false;
                cfgMgrDiag.linesDrawn = false; // force node connections redraw
                static_cast<QWidget*>(obj)->update();
            }
        }
        else if(event->type() == QEvent::MouseMove) {
            if(clicked && selectedNode) {
                const QPoint mousePos = static_cast<QMouseEvent*>(event)->pos();
                const QRect  parentRect = static_cast<QWidget*>(obj)->geometry();

                if(parentRect.contains(mousePos)) {
                    int width = selectedNode->width();
                    int height = selectedNode->height();
                    int x = mousePos.x() - width / 2;
                    int y = mousePos.y() - height / 2;

                    QRect rect(x, y, width, height);

                    if(parentRect.contains(rect)) {
                        selectedNode->setGeometry(rect);
                        cfgMgrDiag.linesDrawn = false;
                        static_cast<QWidget*>(obj)->update();
                    }
                }
            }
        }
        else if(event->type() == QEvent::Paint) {
            if(!cfgMgrDiag.linesDrawn)
                cfgMgrDiag.drawLines();

            if(!clicked && selectedNode)
                cfgMgrDiag.markSelected(selectedNode);
        }
    }

    return QObject::eventFilter(obj, event);
}

}
